#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <modbus.h>
#include <unistd.h>
#include <sys/types.h>
#include <sys/wait.h>
#include <pthread.h>
#include <sys/ipc.h>
#include <sys/shm.h>
#include <errno.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <fcntl.h>
#include "cJSON.h"
#include "msg_queue_peer.h"
#include "shmem.h"
#include "cJSON.h"
union val_t
{
    int b_val;   // bool类型存储空间
    int i_val;   // 整形值存储空间
    float f_val; // 浮点值存储空间
};
struct que_order // 消息队列的消息类型
{
    long tag;     // 消息队列的消息类型
    int key;      // 数据节点唯一标识
    char val[32]; // 数据
};
struct data_node
{
    int key;             // 唯一键值
    int type;            // 数据点类型
    int dev_type;        // 数据点属于哪个设备，根据网关支持的设备自行定义
    union val_t old_val; // 变化上报后需要更新旧值
    union val_t new_val; // 从共享内存取出最新数据，放到new_val中
    int ret;             // 默认为-1，采集成功后设置为0，采集失败再置-1
};
struct addre
{
    int addr;
    int key;
};
static int handle_get(int sock, const char *input) // 获取共享内存的数据 key
{
    // send(sock, "123", 3 ,0);
    char buf[32];
    char buff[32];
    // 初始化创建共享内存
    struct shm_param para;
    if (shm_init(&para, "five", 1024))
    {
        perror("shm_init err\n");
    }
    int *num = shm_getaddr(&para); // 指针指向共享内存的地址->映射
    if (NULL == num)
    {
        perror("shm getaddr err");
    }
    struct data_node *mb;
    mb = (struct data_node *)num + 1; // 往下加1的地址存放数据
    cJSON *json = cJSON_CreateObject();
    for (int i = 0; i < *num; i++) // 从程序上报那里得到num值 循环遍历结构体 向共享空间补充数据
    {
        // modbus读取的数据
        if ((mb + i)->key == 101) // 空调开关
        {
            cJSON *key1 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key1, "key", 101);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key1, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key1", key1);
        }
        else if ((mb + i)->key == 102) // 空调温度
        {
            cJSON *key2 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key2, "key", 102);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key2, "data", (mb + i)->new_val.f_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key2", key2);
        }
        else if ((mb + i)->key == 103) // 制冷开关
        {
            cJSON *key3 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key3, "key", 103);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key3, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key3", key3);
        }
        else if ((mb + i)->key == 104) // 制热开关
        {
            cJSON *key4 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key4, "key", 104);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key4, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key4", key4);
        }
        else if ((mb + i)->key == 105) // 窗帘开关
        {
            cJSON *key5 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key5, "key", 105);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key5, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key5", key5);
        }
        else if ((mb + i)->key == 106) // 投影仪开关
        {
            cJSON *key6 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key6, "key", 106);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key6, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key6", key6);
        }
        // stm32 读取的数据
        else if ((mb + i)->key == 301)
        {
            cJSON *key7 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key7, "key", 301);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key7, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key7", key7);
        }
        else if ((mb + i)->key == 302)
        {
            cJSON *key8 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key8, "key", 302);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key8, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key8", key8);
        }
        else if ((mb + i)->key == 303)
        {
            cJSON *key9 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key9, "key", 303);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key9, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key9", key9);
        }
        else if ((mb + i)->key == 304)
        {
            cJSON *key10 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key10, "key", 304);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key10, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key10", key10);
        }
        else if ((mb + i)->key == 305)
        {
            cJSON *key11 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key11, "key", 305);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key11, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key11", key11);
        }
        else if ((mb + i)->key == 306)
        {
            cJSON *key12 = cJSON_CreateObject();
            cJSON_AddNumberToObject(key12, "key", 306);                      // 使用 AddNumberToObject 添加数字
            cJSON_AddNumberToObject(key12, "data", (mb + i)->new_val.i_val); // 使用 AddNumberToObject 添加整数
            cJSON_AddItemToObject(json, "key12", key12);
        }
    }
    char *jsonString = cJSON_Print(json);
    printf("%s\n", jsonString);
    send(sock, jsonString, strlen(jsonString), 0);
    return 0;
}
static int handle_set(int sock, const char *input) // 定义格式为101-1
{
    char *buf;
    char *buff;
    struct que_order msg;

    buf = strtok(input, "-");
    msg.key = atoi(buf);
    if (msg.key > 300)
    {
        msg.tag = 3;
        buff = strtok(NULL, "-");
        strcpy(msg.val, buff);
        msg_queue_send("five", &msg, sizeof(msg), 0);
    }
    else
    {
        msg.tag = 1;
        buff = strtok(NULL, "-");
        strcpy(msg.val, buff);
        msg_queue_send("five", &msg, sizeof(msg), 0);
    }

    return 0;
}
static int handle_add(int sock, const char *input)
{
    // int number1, number2;

    // // input必须是"data1=1data2=6"类似的格式，注意前端过来的字符串会有双引号
    // sscanf(input, "\"data1=%ddata2=%d\"", &number1, &number2);
    // printf("num1 = %d\n", number1);

    // char reply_buf[HTML_SIZE] = {0};
    // printf("num = %d\n", number1 + number2);
    // sprintf(reply_buf, "%d", number1 + number2);
    // printf("resp = %s\n", reply_buf);
    // send(sock, reply_buf, strlen(reply_buf), 0);

    return 0;
}
/**
 * @brief 处理自定义请求，在这里添加进程通信
 * @param input
 * @return
 */
int parse_and_process(int sock, const char *query_string, const char *input)
{
    // query_string不一定能用的到
    // 网页服务器：
    // parse_and_process函数加入判断，判断传递的数据到底是什么，根据数据不同，处理也不同
    if (strstr(input, "key"))
    {
        // printf("okssssssaaa\n");
        return handle_get(sock, input);
    }
    else if (strstr(input, "-"))
    {
        return handle_set(sock, input);
    }
    else if (strstr(input, "data1=") && strstr(input, "data2="))
    {
        return handle_add(sock, input);
    }
    else // 剩下的都是json请求，这个和协议有关了
    {
        // 构建要回复的JSON数据
        const char *json_response = "{\"message\": \"Hello, client!\"}";

        // 发送HTTP响应给客户端
        send(sock, json_response, strlen(json_response), 0);
    }

    return 0;
}
